package cn.jjxx.modules.demo.controller;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.*;

import cn.jjxx.core.common.controller.BaseController;
import cn.jjxx.core.common.service.impl.CommonServiceImpl;
import cn.jjxx.core.mapper.JsonMapper;
import cn.jjxx.core.query.wrapper.EntityWrapper;
import cn.jjxx.core.utils.CacheUtils;
import cn.jjxx.core.utils.FileUtil;
import cn.jjxx.core.utils.MessageUtils;
import cn.jjxx.core.utils.ObjectUtils;
import cn.jjxx.core.utils.ServletUtils;
import cn.jjxx.core.utils.StringUtils;
import cn.jjxx.core.utils.upload.WebuploaderUtils;
import cn.jjxx.modules.sys.utils.UserUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.framework.customutil.DateUtils;
import org.framework.customutil.date.DateStyle;
import org.framework.customutil.date.DateUtil;
import org.framework.superutil.j2se.ListSortUtil;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * All rights Reserved, Designed By www.jjxxkj.cn
 * 
 * @title: FormDemoController.java
 * @package cn.jjxx.modules.demo.controller
 * @description: 编辑器demo
 * @author: www.jjxxkj.cn
 * @date: 2017年5月18日 下午6:17:24
 * @version V1.0
 * @copyright: 2017 www.jjxxkj.cn Inc. All rights reserved.
 *
 */
@Controller
@RequestMapping("${admin.url.prefix}/demo/form")
public class FormDemoController extends BaseController {
	
	private String FILE_UPLOAD = "upload";
	private String BLOCK_PATH = "/block";

	/**
	 * 
	 * @title: editor
	 * @description: 编辑器
	 * @return
	 * @return: String
	 */
	@RequestMapping("/editor")
	public String editor() {
		return display("editor");
	}

	/**
	 * 
	 * @title: editor
	 * @description: 文件上传
	 * @return
	 * @return: String
	 */
	@RequestMapping("/upload")
	public String upload() {
		return display("upload");
	}
	
	/**
	 * 
	 * @title: editor
	 * @description: 文件上传
	 * @return
	 * @return: String
	 */
	@RequestMapping("/webupload")
	public String webupload() {
		return display("webupload");
	}

	@RequestMapping("/combox")
	public String combox(HttpServletRequest request) {
		return display("combox");
	}

	@RequestMapping("/ajaxCombox")
	@ResponseBody
	public List<?> ajaxCombox(HttpServletRequest request) {
		//String keyword = request.getParameter("keyword");
		return null;
	}
	
	@RequestMapping(value = "mergeOrCheckChunks", method = RequestMethod.POST)
    @ResponseBody
    public String mergeOrCheckChunksa(HttpServletRequest request, HttpServletResponse response, Model model) {
        return mergeOrCheckChunks(request, response, model);
    }

    @RequestMapping(value = "fileSave", method = RequestMethod.POST)
    // 保存上传分片
    public void fileSaves(HttpServletRequest request, HttpServletResponse response) {
        fileSave(request, response);
    }

    @RequestMapping(value = "selectProgressByFileName", method = RequestMethod.POST)
    @ResponseBody
    // 当有文件添加进队列时 通过文件名查看该文件是否上传过 上传进度是多少
    public String selectProgressByFileName(String fileName) {
        FILE_UPLOAD = MessageUtils.getMessage("upload.base.dir");
        String progressRate = null;
        if (fileName != null) {
            Object obj = CacheUtils.get(FILE_UPLOAD, "progressRate_" + fileName);
            if (obj != null) {
                progressRate = obj.toString();
            }

        }
        return "{progressRate :'" + progressRate + "'}";
    }
    
    /**
     * @Description: 根据文件生成的hashKey,获取文件已上传的进度 .<br>
     * @param fileHashs 文件hashKey集合.<br>
     * @author 郑成功 .<br>
     * @date 2018-12-24 下午3:23:14.<br>
     */
    @RequestMapping(value = "getFilesProgress", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> getFilesProgress(String[] fileHashs){
    	Map<String,Object> map = new LinkedHashMap<String, Object>();
    	FILE_UPLOAD = MessageUtils.getMessage("upload.base.dir");
    	for(String fileHash:fileHashs){
    		Object obj = CacheUtils.get(FILE_UPLOAD, "progressRate_" + fileHash);
    		if(!ObjectUtils.isNullOrEmpty(obj)){
    			map.put(fileHash, String.valueOf(obj));
    		}
    	}
    	return map;
    }
	
	public void fileSave(HttpServletRequest request, HttpServletResponse response) {
        FILE_UPLOAD = MessageUtils.getMessage("upload.base.dir");
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        MultiValueMap<String, MultipartFile> fileMap = multiRequest.getMultiFileMap();
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload sfu = new ServletFileUpload(factory);
        sfu.setHeaderEncoding("utf-8");
        String savePath = request.getRealPath("/");
        savePath = new File(savePath) + "/" + FILE_UPLOAD + "/";
        String fileMd5 = request.getParameter("fileMd5");
        // 小于10m的文件FileItem.getFieldName()是得不到chunk的，所以此处不能是空字符串，否则创建文件时会出错
        String chunk = request.getParameter("chunk");
        String id = request.getParameter("formData");
        String fileName = null;
        String fileHash = request.getParameter("fileHash");
        List<FileItem> items1 = new ArrayList<>();
        Set<Map.Entry<String, List<MultipartFile>>> set = fileMap.entrySet();
        Iterator<Map.Entry<String, List<MultipartFile>>> it = set.iterator();
        while (it.hasNext()) {
            Map.Entry<String, List<MultipartFile>> entry = it.next();
            List<MultipartFile> fileList = entry.getValue();
            for (MultipartFile file : fileList) {
                fileName = ((DiskFileItem) ((CommonsMultipartFile) file).getFileItem()).getName();
                try {
                    File file1 = new File(savePath + "/" + CacheUtils.get(FILE_UPLOAD, "fileMd5_" + fileHash).toString());
                    if (!file1.exists()) {
                        file1.mkdir();
                    }
                    chunk = request.getParameter("chunk");
                    File chunkFile = new File(savePath + "/" + CacheUtils.get(FILE_UPLOAD, "fileMd5_" + fileHash) + "/" + chunk);
                    FileUtils.copyInputStreamToFile(file.getInputStream(), chunkFile);
                } catch (Exception e) {
                    e.getStackTrace();
                }
            }
        }
    }
	
	public String mergeOrCheckChunks(HttpServletRequest request, HttpServletResponse response, Model model) {
        FILE_UPLOAD = MessageUtils.getMessage("upload.base.dir");
        String json = null;
        try {
        	String fileMd5 = request.getParameter("fileMd5");
            String chunk = request.getParameter("chunk");
            String progressRate = request.getParameter("progressRate");
            String fileName = request.getParameter("fileName");
            String fileHash = request.getParameter("fileHash");
            String savePath = request.getRealPath("/");
            String chunkSize = request.getParameter("chunkSize");
            Boolean isMerge = Boolean.valueOf(request.getParameter("isMerge"));
            // 文件上传的临时文件保存在项目的temp文件夹下
            savePath = new File(savePath) + "/" + FILE_UPLOAD + "/";
            boolean flag = true;
            if(isMerge){
            	WebuploaderUtils.MergeFileBlock(savePath, fileMd5, fileHash, fileName, null);
            }else{
            	flag = WebuploaderUtils.uploadFileBlock(savePath, fileHash, progressRate, fileMd5, chunk, Integer.valueOf(chunkSize), null);
            }
            if (flag) {
                // 上传过
                json = "{\"ifExist\":1}";
            } else {
                // 没有上传过
                json = "{\"ifExist\":0}";
            }
        } catch (Exception e) {
            e.getStackTrace();
        }
        return json;
    }
	
	public boolean saveFile(){
		return true;
	}

}
